/**
 * 蓝牙升级固件
 */

function updateFile(dataArray) {
	const chunkSize = 128 // 蓝牙传输一般最大为128字节/包
	let offset = 0

	function sendChunk() {
		if (offset >= dataArray.length) {
			return
		}
		const chunk = dataArray.slice(offset, offset + chunkSize)
		uni.writeBLECharacteristicValue({
			deviceId,
			serviceId,
			characteristicId,
			value: chunk.buffer,
			success: function(res) {
				console.log(`发送进度: ${offset}/${dataArray.length}`)
				offset += chunkSize
				setTimeout(sendChunk, 50) // 控制发送间隔，保证接收方处理时间
			},
			fail: function(err) {
				console.error('发送失败', err)
			}
		})
	}

	sendChunk()


}




//写入二进制
function WriteBase(deviceId, value, callback) {
	var serviceId = getApp().globalData.bleObj.serviceId;
	var characteristicId = getApp().globalData.bleObj.characteristicId;
	uni.writeBLECharacteristicValue({
		// 这里的 deviceId 需要在 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
		deviceId,
		// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
		serviceId,
		// 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
		characteristicId,
		// 这里的value是ArrayBuffer类型
		value: value,
		success(res) {
			if (res.errCode == 0 || res.errno == 0) {
				if (callback) {
					callback(res);
				}
			} else {
				console.log(res, '写入二进制success');
			}
		},
		fail(res) {
			console.log(res, '写入二进制fail');
		}
	})
}

function writeStrToRead(str, callback, isAuto = true) {
	var deviceId = getApp().globalData.bleObj.deviceId;
	var state = getApp().globalData.bleObj.state;
	if (deviceId != '' && state) {
		var command = new Uint8Array(str.match(/[\da-f]{2}/gi).map(function(h) {
			return parseInt(h, 16)
		}));
		WriteBase(deviceId, command.buffer, function(res) {
			if (callback) {
				callback(res);
			}
		});
	} else {
		if (!isAuto) {
			//msg(language.b16);
		}
	}
}

//写入读取命令03
function writeToRead(start, len, callback, isAuto = true) {
	var deviceId = getApp().globalData.bleObj.deviceId;
	var state = getApp().globalData.bleObj.state;
	if (deviceId != '' && state) {
		var command = readCommand(start, len);
		WriteBase(deviceId, command, function(res) {
			if (callback) {
				callback(res);
			}
		});
	} else {
		if (!isAuto) {
			//msg(language.b16);
		}
	}
}

function writeToWrite(statu, start, len, txt = '', callback) {
	var deviceId = getApp().globalData.bleObj.deviceId;
	var state = getApp().globalData.bleObj.state;
	if (deviceId != '' && state) {
		var command = buildCommand(statu, start, len, txt);
		WriteBase(deviceId, command, function(res) {
			if (callback) {
				callback(res);
			}
		});
	} else {
		console.log('发送指令失败');
	}
}

const top = 'DD';
const read = '03';
const write = '06';

//组装读取命令
/**
 * @param {Object} statu A5
 * @param {Object} start FA FB
 * @param {Object} len
 * @param {Object} txt
 */
function buildCommand(statu, start, len, txt = '') {
	var d = top + statu + start + len + txt;
	var crc16 = checkCRC16(start + len + txt);
	d = d + crc16 + '77';
	console.log('发送内容command：', d);
	var typedArray = new Uint8Array(d.match(/[\da-f]{2}/gi).map(function(h) {
		return parseInt(h, 16)
	}));
	return typedArray.buffer;
}

function buildCommandText(statu, start, len, txt = '') {
	var d = top + statu + start + len + txt;
	var crc16 = checkCRC16(start + len + txt);
	d = d + crc16 + '77';
	console.log('发送内容command：', d);
	return d;
}


//arrayBuffer转16进制字符串
function ab2hex(buffer) {
	const hexArr = Array.prototype.map.call(
		new Uint8Array(buffer),
		function(bit) {
			return ('00' + bit.toString(16)).slice(-2)
		}
	)
	return hexArr.join('');
}

//验证CRC16
function checkCRC16(hexString) {
	// 移除可能存在的空格或非十六进制字符
	const cleanHex = hexString.replace(/[^0-9A-Fa-f]/g, '');
	// 确保是偶数个字符，每两个字符代表一个字节
	if (cleanHex.length % 2 !== 0) {
		throw new Error("十六进制字符串长度必须为偶数");
	}
	let sum = 0;
	// 遍历每两个字符（一个字节）
	for (let i = 0; i < cleanHex.length; i += 2) {
		const byteHex = cleanHex.substr(i, 2);
		const byteValue = parseInt(byteHex, 16);
		sum += byteValue;
	}
	// 取反，得到校验码
	let checksum = (~sum + 1) & 0xFFFF; // 同样保留低16位
	// 转换为4位大写十六进制字符串
	return checksum.toString(16).toUpperCase().padStart(4, '0');
}

//解包
function solutionData(str) {
	str = str.toUpperCase();
	var packages = {};
	packages.top = str.substr(0, 4);
	packages.length = parseInt('0x' + str.substr(4, 4));
	packages.crc16 = str.substr(str.length - 6, 6);
	var data = str.substr(8, packages.length * 2);
	packages.data = data;
	return packages;
}


//检流电阻
function parseShuntResistance(data) {
	let value;
	if (typeof data === 'string') {
		// 移除可能的 0x 前缀并解析
		value = parseInt(data.replace(/^0x/i, ''), 16);
	} else if (typeof data === 'number') {
		value = data;
	} else {
		throw new Error('无效输入类型');
	}

	// 检查是否为 2 字节范围
	if (isNaN(value) || value < 0 || value > 0xFFFF) {
		throw new Error('数据超出 2 字节范围 (0x0000 ~ 0xFFFF)');
	}

	// 获取最高位 (bit 15)
	const msb = (value >> 15) & 1;

	// 取低 15 位作为数值
	const magnitude = value & 0x7FFF; // 0x7FFF = 32767

	// 判断单位
	const unit = msb === 1 ? 0.01 : 0.1; // 单位：mΩ

	// 计算实际阻值
	const resistance_mohm = magnitude * unit;

	return resistance_mohm;
}


//16进制转明文
function algorithm(name, v1) {
	name = name.toUpperCase();
	var value = 0;
	//console.log(name, v1);
	switch (name) {
		case '01':
			var v = new Int16Array([parseInt("0x" + v1, 16)])[0];
			value = parseFloat((v / 100).toFixed(1));
			break;
		case '00':
		case '16':
		case '17':
		case '18':
		case '19':
			var v = parseInt("0x" + v1);
			value = parseFloat((v / 100).toFixed(1));
			break;
		case '08':
		case '09':
		case '10':
		case '11':
		case '12':
		case '13':
		case '14':
		case '15':
			var v = parseInt("0x" + v1);
			value = parseFloat(((v - 2731) * 0.1).toFixed(1));
			break;
		case '24':
			var v = parseInt("0x" + v1);
			value = parseFloat((v * 10).toFixed(1));
			break;
		case '25':
			var v = parseInt("0x" + v1);
			value = parseFloat(((65536 - v) * 10).toFixed(1));
			break;
		case '28':
			if(!v1||v1.length<1){
				break;
			}
			value = parseShuntResistance("0x" + v1);
			break;
		default:
			var v = parseInt("0x" + v1);
			value = v;
			break;
	}
	return value;
}

const hexMap = {
	'0': '0000',
	'1': '0001',
	'2': '0010',
	'3': '0011',
	'4': '0100',
	'5': '0101',
	'6': '0110',
	'7': '0111',
	'8': '1000',
	'9': '1001',
	'a': '1010',
	'b': '1011',
	'c': '1100',
	'd': '1101',
	'e': '1110',
	'f': '1111'
};
/**
 * @param {Object} hexStr
 * 
 * 
 */
function hexToBitsFast(hexStr) {
	return hexStr.toLowerCase()
		.split('')
		.map(c => hexMap[c] || '0000')
		.join('');
}


/**
 * 将目标电阻值（单位：mΩ）编码为符合协议的2字节发送指令
 * 支持 0.1, 0.2, 0.3, 0.4 等常见小数
 *
 * @param {number} resistance - 目标阻值，单位 mΩ（例如 0.2）
 * @returns {Object} 包含 hexValue、bytes、hexString 等信息
 */
function encodeResistanceForSend(resistance) {
	// 校验输入
	if (typeof resistance !== 'number' || resistance < 0 || resistance > 3276.7) {
		throw new Error('电阻值必须是 0 ~ 3276.7 mΩ 之间的数字');
	}

	let value = null;
	let rawHex = 0;

	// 方案1：尝试使用 0.1mΩ 单位（推荐，高位=0）
	const as0_1 = resistance / 0.1;
	if (Number.isInteger(as0_1) && as0_1 <= 0x7FFF) {
		value = Math.round(as0_1); // 低15位数值
		rawHex = value & 0x7FFF; // 最高位自动为0
	}
	// 方案2：尝试使用 0.01mΩ 单位（高位=1）
	else {
		const as0_01 = resistance / 0.01;
		if (Number.isInteger(as0_01) && as0_01 <= 0x7FFF) {
			value = Math.round(as0_01);
			rawHex = (1 << 15) | (value & 0x7FFF); // 设置最高位为1
		} else {
			throw new Error(`无法精确表示阻值 ${resistance} mΩ`);
		}
	}
	const hexString = rawHex.toString(16).padStart(4, '0').toUpperCase();
	return hexString
}

//明文转16进制
function encryption(name, v1) {
	name = name.toUpperCase();
	var v = 0;
	switch (name) {
		case '00':
		case '01':
		case '16':
		case '17':
		case '18':
		case '19':
			v = Math.round(v1 * 100);
			break;
		case '08':
		case '09':
		case '10':
		case '11':
		case '12':
		case '13':
		case '14':
		case '15':
			v = Math.round(v1 * 10 + 2731);
			break;
		case '24':
			v = Math.round(v1 / 10);
			break;
		case '25':
			v = Math.round(65536 - (v1 / 10));
			break;
		case '28':
			v = encodeResistanceForSend(v1);
			break;
		default:
			v = Math.round(v1);
			break;
	}
	var v2 = v.toString(16).toUpperCase();
	if (v2 == '') {
		return '';
	}
	if (v2.indexOf('-') >= 0) {
		return '';
	}
	if (v2.length == 1) {
		return '000' + v2;
	} else if (v2.length == 2) {
		return '00' + v2;
	} else if (v2.length == 3) {
		return '0' + v2;
	} else if (v2.length == 4) {
		return v2;
	} else {
		return '';
	}
}

export default {
	WriteBase: WriteBase,
	writeStrToRead: writeStrToRead,
	writeToWrite: writeToWrite,
	buildCommand: buildCommand,
	buildCommandText: buildCommandText,
	bufferToHex: ab2hex,
	checkCRC16: checkCRC16,
	solutionData: solutionData,
	algorithm: algorithm,
	encryption: encryption,
}